﻿/**
 * 封装了一系列帮助方法，用来支持模型见的关系。
 */
Ext.define('Happy.data.relation.RelationUtil', {
    singleton: true,

    /**
     * 设置记录相关的数据，如：订单的订单项列表。
     * 
     * @param {Ext.data.Model} record
     * @param {Object} data
     */
    setRelatedValue: function (record, data) {
        var me = this;

        if (!record.relation) {
            return;
        }

        me.setOneToManyRelatedValue(record, data);
    },

    /**
     * 设置记录相关的 1：N 数据，如：订单的订单项列表。
     * 
     * @param {Ext.data.Model} record
     * @param {Object} data
     */
    setOneToManyRelatedValue: function (record, data) {
        if (!record.relation.hasMany) {
            return;
        }

        Ext.Array.each(record.relation.hasMany, function (relation) {
            var relationName = relation.name;

            if (relation.isNested) {
                if (!record[relationName]) {
                    record[relationName] = Ext.create(relation.store, {
                        isNested: relation.isNested,
                        data: data[relationName]
                    });

                    if (!record.phantom) {
                        record[relationName].on('add', function () {
                            record.setDirty();
                        });
                        record[relationName].on('update', function () {
                            record.setDirty();
                        });
                        record[relationName].on('remove', function () {
                            record.setDirty();
                        });
                    }
                }
                else {
                    record[relationName].loadData(data[relationName]);
                }
            }
            else {
                if (!record[relationName]) {
                    record[relationName] = Ext.create(relation.store, {
                        isNested: relation.isNested,
                        arguments: [{
                            property: relation.foreignKey,
                            dataType: relation.foreignKeyDataType,
                            value: record.getId()
                        }]
                    });
                }
            }

            record.fireEvent(relationName.toLowerCase() + "changed", record, record[relationName]);
        });
    },

    /**
     * 将记录相关的数据写入到要提交的数据中。
     * 
     * @param {Ext.data.writer.Writer} writer
     * @param {Ext.data.Model} record
     * @param {Object} data
     */
    writeRelatedData: function (writer, record, data) {
        var me = this;

        if (!record.relation) {
            return;
        }

        me.writeOneToManyRelatedData(writer, record, data);
    },

    /**
     * 将记录相关的 1：N 数据写入到要提交的数据中。
     * 
     * @param {Ext.data.writer.Writer} writer
     * @param {Ext.data.Model} record
     * @param {Object} data
     */
    writeOneToManyRelatedData: function (writer, record, data) {
        if (!record.relation.hasMany) {
            return;
        }

        Ext.Array.each(record.relation.hasMany, function (relation) {
            var relationName = relation.name;

            var newRecords = record[relationName].getNewRecords();
            var updatedRecords = record[relationName].getUpdatedRecords();
            var removedRecords = record[relationName].getRemovedRecords();

            var changeSet = [];
            Ext.Array.each(newRecords, function (newRecord) {
                var newData = writer.getRecordData(newRecord);
                newData.RecordState = "Added";
                changeSet.push(newData);
            });
            Ext.Array.each(updatedRecords, function (updatedRecord) {
                var updatedData = writer.getRecordData(updatedRecord);
                updatedData.RecordState = "Modified";
                changeSet.push(updatedData);
            });
            Ext.Array.each(removedRecords, function (removedRecord) {
                var removedData = writer.getRecordData(removedRecord);
                removedData.RecordState = "Deleted";
                changeSet.push(removedData);
            });

            data[relationName] = changeSet;
        });
    }
});